package core;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;

public class VectorialObject implements Object2D, Selectable {

	private static final Double VERTICE_SIZE = 10.0;
	
	private List<Point2D.Double> points;
	
	private Line2D.Double line;
	
	private Rectangle2D.Double rect;
	
	private boolean selected = false;

	private Stroke stroke;
	
	private DrawStyle style;
	
	public VectorialObject(DrawStyle style) {
		points = new ArrayList<Point2D.Double>();
		line = new Line2D.Double();
		rect = new Rectangle2D.Double();	
		rect.width = VERTICE_SIZE;
		rect.height = VERTICE_SIZE;
		stroke = new BasicStroke();
		this.style = style;
	}
	
	@Override
	public void draw(OurGraphics g2) {
		
		g2.setColor(Color.BLACK);
		g2.getRealGraphics().setStroke(stroke);

		Point2D.Double startPoint = null;
		Point2D.Double endPoint = null;
		
		int pointsSize = points.size();
		
		if(points.size() > 0) {
			startPoint = points.get(0);
			
			if(selected)
				drawVertice(startPoint, g2);
		}
		
		for(int i = 1; i < pointsSize; i++) {
			endPoint = points.get(i);
			
			line.x1 = startPoint.x;
			line.y1 = startPoint.y;
			line.x2 = endPoint.x;
			line.y2 = endPoint.y;
			
			g2.drawLine((int)line.x1, (int)line.y1, (int)line.x2, (int)line.y2);
			
			if(selected)
				drawVertice(endPoint, g2);
			
			startPoint = endPoint;
		}
		
		if(style == DrawStyle.CLOSED && pointsSize > 1) {
			startPoint = points.get(0);
			line.x1 = startPoint.x;
			line.y1 = startPoint.y;
			line.x2 = endPoint.x;
			line.y2 = endPoint.y;
			g2.drawLine((int)line.x1, (int)line.y1, (int)line.x2, (int)line.y2);
		}

	}
	
	private void drawVertice(Point2D.Double pt, OurGraphics g2) {
		rect.x = pt.x - VERTICE_SIZE/2;
		rect.y = pt.y - VERTICE_SIZE/2;
		g2.getRealGraphics().fill(rect);
	}
	
	public boolean intersect(Point2D.Double pt) {
		
		int ptsSize = points.size()-1;
		for(int i = 0; i < ptsSize; i++){
			if(lineIntersection(points.get(i), points.get(i+1), pt, 5)){
				return true;
			}
		}
		
		return lineIntersection(points.get(ptsSize), points.get(0), pt, 5);
	}
	
	private boolean lineIntersection(Point2D.Double p1, Point2D.Double p2, Point2D.Double p, double error) {
		
		double xMax = Math.max(p1.x, p2.x);
		double xMin = Math.min(p1.x, p2.x);
		
		double coefAng = (p2.y - p1.y)/(p2.x - p1.x);
		double coefLin = p1.y - coefAng*p1.x;
		
		if(p.x >= xMin - error && p.x <= xMax + error) {
			double yMax = coefAng * p.x + coefLin; 
			double yMin = coefAng * p.x + coefLin;
			
			if(p.y >= yMin - error && p.y <= yMax + error){
				return true;
			}
		}
			
		
		return false;
	}
	
	public void addVertice(Point2D.Double pt) {
		points.add(pt);
	}
	
	public Point2D.Double getVertice(int v) {
		return points.get(v);
	}

	@Override
	public boolean isSelected() {
		return selected;
	}

	@Override
	public void setSelected(boolean b) {
		selected = b;
	}
	
	public int getVerticeCount() {
		return points.size();
	}
	
	public enum DrawStyle {
		OPENED,
		CLOSED
	}
	
	public static void main(String args[]) {
		
		Point2D.Double p1 = new Point2D.Double(1, 1);
		Point2D.Double p2 = new Point2D.Double(3, 3);
		Point2D.Double p = new Point2D.Double(1.5, 1.5);
		
		VectorialObject obj = new VectorialObject(DrawStyle.OPENED);
		
		if(obj.lineIntersection(p1, p2, p, 1)){
			System.out.println("Intersepta");
		}
	}
	

}
